package cz.data.gateway.api.listener;

import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import cz.data.common.core.DataConstant;
import cz.data.common.utils.SecurityUtil;
import cz.data.common.utils.ThrowableUtil;
import cz.data.gateway.api.route.RouterUtils;
import cz.data.gateway.api.service.impl.RouteService;
import cz.data.gateway.model.dto.GatewayRouteVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.event.EventListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;

@Slf4j
@Component
public class SpringEventListener {

    @Autowired
    WebClient webClient;
    @Autowired
    RouteService routeService;

    @EventListener(ApplicationReadyEvent.class)
    public void applicationReady(ApplicationReadyEvent event) {
        ConfigurableApplicationContext context = event.getApplicationContext();
        NacosDiscoveryProperties discoveryProperties = context.getBean(NacosDiscoveryProperties.class);
        ConfigurableEnvironment environment = context.getEnvironment();
        String ip = discoveryProperties.getIp();
        String banner = "\n-----------------------------------------\n" +
                "服务启动成功，时间：" + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()) + "\n" +
                "服务名称：" + environment.getProperty("spring.application.name") + "\n" +
                "端口地址：" + ip + ":" + environment.getProperty("server.port") + "\n" +
                "-----------------------------------------";
        log.info(banner);
        String clientId = discoveryProperties.getMetadata().get("client-id");
        String serviceName = discoveryProperties.getService();
        String nacosServiceToken = SecurityUtil.createBasicToken(serviceName, clientId);
        log.debug("当前服务密匙: {}, 服务内部鉴权Token: {}", clientId, nacosServiceToken);
        log.debug("loadRouteDefinition, 开始初使化路由");
        String api = "http://data-gateway-admin/api/admin/gateway/routes/release";
        AtomicBoolean loaded = new AtomicBoolean(true);
        while (loaded.get()) {
            ThrowableUtil.throwable(() -> Thread.sleep(3000));
            webClient.get()
                    .uri(api)
                    .accept(MediaType.APPLICATION_JSON)
                    .acceptCharset(StandardCharsets.UTF_8)
                    .header(DataConstant.Token.SERVICE_HEADER, nacosServiceToken)
                    .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                    .exchangeToFlux(response -> response.bodyToFlux(GatewayRouteVo.class))
                    .doOnError(throwable -> log.error("初始化路由失败: {}", throwable.getMessage()))
                    .doOnComplete(() -> loaded.set(false))
                    .map(RouterUtils::toRouter)
                    .filter(Objects::nonNull)
                    .subscribe(router -> routeService.save(router));
        }
        log.info("路由初始化成功");
    }
}
